
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Game extends Canvas
{
	/** The message to display which waiting for a key press */
	private String message = "";
	private BufferStrategy strategy;
	private SpriteStore spriteStorage;
	public GameThread t;
	private Clip clip;
	
	
	public Player player;	
	public Laser laser;
	public DialogueBox dialogue;
	public Elevator elevator;
	int x, y = 0;
	
	
	boolean rightClick, leftClick = true;
	
	//test variables
	Entity background;
	HashMap<BlockLocation, Entity> tileMap;
	public ArrayList<Entity> objects;
	boolean press_W = false;
	boolean press_S = false;
	boolean win = false;

	
	public Game()
	{
		JFrame container = new JFrame("IceMan");
		
		JPanel panel = (JPanel) container.getContentPane();
		panel.setPreferredSize(new Dimension(800,600));
		panel.setLayout(null);
		
		setBounds(0,0,800,600);
		panel.add(this);
		
		//manually refresh the panel
		setIgnoreRepaint(true);
		
		//make the window visable and NOT resizable
		container.setBounds(0, 0, 800, 600);
		container.setResizable(false);
		container.setVisible(true);
		//close the game when ("x" is pressed) 
		container.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		
		BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
		cursorImg.createGraphics().drawOval(4, 4, 8, 8);

		// Create a new blank cursor.
		Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
		    cursorImg, new Point(0, 0), "blank cursor");

		// Set the blank cursor to the JFrame.
		container.getContentPane().setCursor(blankCursor);



		addMouseMotionListener(new MouseMotionHandler(this));
		addMouseListener(new MouseClickHandler(this));
		addKeyListener(new KeyInputHandler(this));

		
		// request the focus so key events come to us
		requestFocus();

		// create the buffering strategy which will allow AWT
		// to manage our accelerated graphics
		//This part is written by Kevin Glass, and his tutorial on cokeandcode.com
		
		createBufferStrategy(2);
		strategy = getBufferStrategy();
		spriteStorage = new SpriteStore();
		
		objects = new ArrayList<Entity>();
		//start the game
		startGame();
	}

	
	public SpriteStore getStorage()
	{
		return spriteStorage;
	}
	public void startGame()
	{
		player = new Player(this, 544, 2272, spriteStorage.getSprite("res//walk.png", 3));
		background = new Entity(this, 0, 0, spriteStorage.getSprite("res//land.jpg", 1));
		tileMap = MapReader.readMap(this, "res//map.txt");
		dialogue = new DialogueBox();
		laser = new Laser(this);

		try 
		{
			Clip clip = AudioSystem.getClip();
			clip.open(AudioSystem.getAudioInputStream(new File("res//Music.wav")));
			clip.loop(clip.LOOP_CONTINUOUSLY);
		} catch(Exception e)
		{
			System.out.println(e);
		}
		
		try {
			dialogue.enable("res//test.txt");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	public void update(long gameTime)
	{
		player.update(gameTime);
		laser.update();
		for (Entity entity: tileMap.values())
		{
			if (entity != null)
			{
				entity.update(gameTime);
			}
		}
		for (Entity e: objects)
		{
			e.update(gameTime);
		}
		if (player.x > 6600 && !win)
		{
			try {
				dialogue.enable("res//win.txt");
			} catch (FileNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			win = true;
		}
	}
	

	public void draw()
	{
		//gets graphics, draws a black background

		Graphics2D g = (Graphics2D) strategy.getDrawGraphics();

		g.setColor(Color.BLACK);
		g.fillRect(0,0,1000,1000);
		


		background.draw(g);
		//keeps players centered on screen, put non-moving elements of screen before this
		int offsetX = player.x - getWidth()/2;
		int offsetY = player.y - getHeight()/2;
		g.translate(-offsetX, -offsetY);

		for (Entity tile: tileMap.values())
		{
			if (tile != null)
			{
				tile.draw(g);
			}
		}

		for (Entity object: objects)
		{
			if (object != null)
			{
				object.draw(g);
			}
		}

		// Dialogue box must be drawn after tiles but before laser.
		g.translate(offsetX, offsetY);
		
		g.fillRect(45, 45, 310, 20);
		g.setColor(Color.RED);
		
		g.fillRect(50, 50, player.health, 10);
		Font f = new Font("SansSerif", Font.PLAIN, 18);
		g.setFont(f);
		g.setColor(Color.WHITE);

		g.drawString("HEALTH", 50, 30);
		dialogue.draw(g);
		g.translate(-offsetX, -offsetY);
		
		
		player.draw(g);
	
		laser.draw(g);


		//releases resources manually
		g.dispose();
		
		//refreshes the canvas
		strategy.show();
	}
	
	public void moveHorizontal(int move)
	{
		x += move;
	}
	
	public void moveVertical(int move)
	{
		y += move;
	}
	
	public void setVelocityX(int vel)
	{
		player.speed.setvX(vel);
	}
	public void setVelocityY(int vel)
	{
		player.speed.setvY(vel);
	}
	
	public void startDialogue(String filePath) throws FileNotFoundException
	{
		dialogue.enable(filePath);
	}
	
	public void advanceText()
	{
		dialogue.advance();
	}
	
	public void freezeAt(int x, int y)
	{
		int blockX = x - x % MapReader.tileWidth;
		int blockY = y - y % MapReader.tileHeight;
		
		Entity tile = tileMap.get(new BlockLocation(blockX, blockY));
		if (tile instanceof Freezable)
		{
			((Freezable) tile).freeze();
		}
	}
	
	public void meltAt(int x, int y)
	{
		System.out.println("melt at");
		int blockX = x - x % MapReader.tileWidth;
		int blockY = y - y % MapReader.tileHeight;
		
		Entity tile = tileMap.get(new BlockLocation(blockX, blockY));
		if (tile instanceof Freezable)
		{
			System.out.println("melting");
			((Freezable) tile).melt();
		}
		
	}
	
	
	public static void main(String[] args)
	{
		Game p = new Game();
		GameThread t = new GameThread(p);
		p.t = t;
		p.t.run();
	}

}
